//
// Created by Administrator on 2024/10/25.
//
#include "ResourcesProcessor.h"
#include "../constant/StringUtils.h"
#include "../utils/DateUtils.h"


ResourcesProcessor::ResourcesProcessor() {
    pool = ConnectionPool::getInstance();

}

std::vector<DicomArchive> ResourcesProcessor::getList(std::string &request_id) {
    auto client = pool->getConnection();
    if (!client) {
        delete client->connect;
        throw std::runtime_error("pool get connection field: ");
    }

    auto sql = "SELECT request_id,task_status FROM dicom_archive WHERE request_id = ?";
    sql::PreparedStatement *prep_stmt = client->connect->prepareStatement(sql);
    prep_stmt->setString(1, request_id);

    sql::ResultSet *res = prep_stmt->executeQuery();
    std::vector<DicomArchive> results;
    while (res->next()) {
        DicomArchive arc;
        arc.request_id = res->getString("request_id");
        arc.task_status = res->getInt("task_status");
        results.push_back(arc);
    }

    delete client->connect;
    delete res;
    delete prep_stmt;
    return results;
}

bool ResourcesProcessor::create(std::string &request_id, std::string &hosp_code, std::string &study_instance_uid) {

    auto client = pool->getConnection();
    if (!client) {
        delete client->connect;
        throw std::runtime_error("pool get connection field: ");
    }

    std::vector<std::string> columns = {"request_id", "hosp_code", "study_instance_uid", "task_status", "created_time"};
    std::string columnsStr = std::format("{}", StringUtils::join(columns, ","));
    std::string valuesStr = "?";
    std::for_each(columns.begin() + 1, columns.end(), [&valuesStr](const auto &) { valuesStr += ", ?"; });

    std::string query = std::format("INSERT INTO dicom_archive({}) VALUES({})", columnsStr, valuesStr);

    sql::PreparedStatement *prep_stmt = client->connect->prepareStatement(query);
    prep_stmt->setString(1, request_id);
    prep_stmt->setString(2, hosp_code);
    prep_stmt->setString(3, study_instance_uid);
    prep_stmt->setInt(4, static_cast<int32_t>(ArchiveEnumNotified::UNNotification));
    prep_stmt->setString(5, DateUtils::getCurrentDateString());

    int rows_affected = prep_stmt->executeUpdate();
    delete prep_stmt;
    delete client->connect;

    if (rows_affected < 1) {
        throw std::runtime_error("Insert  dicom_archive operation did not affect exactly one row! ");
    }

    return true;
}

bool ResourcesProcessor::update(const DicomArchive &arc) {
    auto request_id = arc.request_id;
    auto res = getList(request_id);
    if (res.empty()) {
        throw std::runtime_error(" dicom_archive record  not exist! ");
    }

    auto client = pool->getConnection();
    if (!client) {
        delete client->connect;
        throw std::runtime_error("pool get connection field: ");
    }

    std::string columns = "task_status =? ,is_notified =? ,modified_time=? ,remark=?";
    std::string where = "request_id=?";
    std::string query = std::format("update dicom_archive set {} where {}", columns, where);

    sql::PreparedStatement *prep_stmt = client->connect->prepareStatement(query);
    prep_stmt->setInt(1, arc.task_status);
    prep_stmt->setInt(2, arc.is_notified);
    prep_stmt->setString(3, arc.modified_time);
    prep_stmt->setString(4, arc.remark);
    prep_stmt->setString(5, request_id);

    int rows_affected = prep_stmt->executeUpdate();
    delete prep_stmt;
    delete client->connect;

    if (rows_affected < 1) {
        throw std::runtime_error("update dicom_archive operation did not affect exactly one row! ");
    }

    return true;
}

